package com.trsvax.gwthello.services.dispatcher;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.Map;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;

import org.apache.tapestry5.services.Dispatcher;
import org.apache.tapestry5.services.Request;
import org.apache.tapestry5.services.RequestGlobals;
import org.apache.tapestry5.services.Response;
import org.slf4j.Logger;

import com.google.visualization.datasource.Capabilities;
import com.google.visualization.datasource.DataSourceHelper;
import com.google.visualization.datasource.DataSourceRequest;
import com.google.visualization.datasource.QueryPair;
import com.google.visualization.datasource.base.DataSourceException;
import com.google.visualization.datasource.base.TypeMismatchException;
import com.google.visualization.datasource.datatable.ColumnDescription;
import com.google.visualization.datasource.datatable.DataTable;
import com.google.visualization.datasource.datatable.TableRow;
import com.google.visualization.datasource.datatable.value.DateTimeValue;
import com.google.visualization.datasource.datatable.value.Value;
import com.google.visualization.datasource.datatable.value.ValueType;
import com.google.visualization.datasource.query.Query;
import com.ibm.icu.util.GregorianCalendar;
import com.ibm.icu.util.TimeZone;

public class DataSourceDispatcher implements Dispatcher {
	private final Logger logger;
	private final RequestGlobals requestGlobals;

	public DataSourceDispatcher(Logger logger, RequestGlobals requestGlobals) {
		this.logger = logger;
		this.requestGlobals = requestGlobals;
	}

	public boolean dispatch(Request request, Response response) throws IOException {

		if (!request.getPath().contains("datasource"))
			return false;

		logger.info("get data");
		DataSourceRequest dsRequest = null;
		PrintWriter pw = response.getPrintWriter("text/html");
		try {
			dsRequest = new DataSourceRequest(requestGlobals.getHTTPServletRequest());
			QueryPair query = DataSourceHelper.splitQuery(dsRequest.getQuery(), Capabilities.SELECT);
			DataTable data = generateMyDataTable(query.getDataSourceQuery(), requestGlobals.getHTTPServletRequest());

			DataTable newData = DataSourceHelper
					.applyQuery(query.getCompletionQuery(), data, dsRequest.getUserLocale());

			String d = DataSourceHelper.generateResponse(newData, dsRequest);

			pw.print(d);

		} catch (DataSourceException e) {
			// throw new IOException(e.getMessage());
			// DataSourceHelper.setServletErrorResponse(e, dsRequest, resp);
			if (dsRequest == null) {
				throw new IOException(e.getLocalizedMessage());

			} else {
				pw.print(DataSourceHelper.generateErrorResponse(e, dsRequest));
			}

		}
		pw.flush();
		pw.close();
		return true;
	}

	private DataTable generateMyDataTable(Query query, HttpServletRequest req) throws TypeMismatchException {
		String tableID = req.getParameter("tableId");
		// if ((tableID != null) && (tableID.equalsIgnoreCase("planets"))) {
		// return generatePlanetsTable(query);
		// }
		return generateAnimalsTable(query);
	}

	private static Map<String, String> animalLinksByName = new TreeMap<String, String>();
	static {
		animalLinksByName.put("Fish", "http://en.wikipedia.org/wiki/Fish");
		animalLinksByName.put("Dog", "http://en.wikipedia.org/wiki/Dog");
		animalLinksByName.put("Cat", "http://en.wikipedia.org/wiki/Cat");
		animalLinksByName.put("Cow", "http://en.wikipedia.org/wiki/Cow");
		animalLinksByName.put("Tiger", "http://en.wikipedia.org/wiki/Tiger");
		animalLinksByName.put("Elephant", "http://en.wikipedia.org/wiki/Elephant");
		animalLinksByName.put("Goat", "http://en.wikipedia.org/wiki/Goat");
		animalLinksByName.put("Aye-aye", "http://en.wikipedia.org/wiki/Aye-aye");
		animalLinksByName.put("Sloth", "http://en.wikipedia.org/wiki/Sloth");
	}

	private static final String ANIMAL_COLUMN = "animal";
	private static final String ARTICLE_COLUMN = "article";

	private DataTable generateAnimalsTable(Query query) throws TypeMismatchException {
		DataTable data = new DataTable();
		data.addColumn(new ColumnDescription("d", ValueType.DATETIME, "Date"));
		data.addColumn(new ColumnDescription("pencils", ValueType.NUMBER, "Sold Pencils"));
		// data.addColumn(new ColumnDescription("title1", ValueType.TEXT,
		// "title1"));
		// data.addColumn(new ColumnDescription("t1", ValueType.TEXT, "text1"));
		data.addColumn(new ColumnDescription("pens", ValueType.NUMBER, "Sold Pens"));
		// data.addColumn(new ColumnDescription("title2", ValueType.TEXT,
		// "title2"));
		// data.addColumn(new ColumnDescription("t2", ValueType.TEXT, "text2"));

		// Populate the data table
		GregorianCalendar cal = new GregorianCalendar();
		TimeZone zone = TimeZone.getTimeZone("GMT");
		cal.setTimeZone(zone);
		cal.setTime(new Date());

		for (int i = 0; i < 100; i++) {
			TableRow row = new TableRow();
			cal.add(GregorianCalendar.MINUTE, 1);

			Value v = new DateTimeValue(cal);
			row.addCell(v);
			row.addCell(10);
			// row.addCell("");
			// row.addCell("");
			row.addCell(20);
			// row.addCell("");
			// row.addCell("");

			data.addRow(row);
		}
		return data;
	}

}
